package kr.pe.johnkim.pushchat.mobile.service;

import kr.pe.johnkim.pushchat.mobile.dao.PushChatAnnouncementDao;
import kr.pe.johnkim.pushchat.mobile.domain.PushChatAnnouncement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

/**
 * @author : John_Kim <cale9797@gmail.com>
 * @date : 13. 9. 13.
 */
@Service
public class PushChatAnnouncementServiceImpl implements PushChatAnnouncementService {

    // SLF4J Logging
    private Logger logger = LoggerFactory.getLogger(PushChatDiaryServiceImpl.class);

    @Autowired
    private PushChatAnnouncementDao pushChatAnnouncementDao;

    // 생성 할 썸네일 이미지 가로 크기.
    private @Value("${announcement.thumbnail.width}") int announcementThumbnailWidth;

    // 생성 할 썸네일 이미지 세로 크기.
    private @Value("${announcement.thumbnail.height}") int announcementThumbnailHeight;

    /**
     * 공지사항을 등록 한다.
     *
     * @param pushChatAnnouncement
     */
    @Override
    public void registerAnnouncement(PushChatAnnouncement pushChatAnnouncement) {
        logger.info("registerAnnouncement");
        pushChatAnnouncementDao.registerAnnouncement(pushChatAnnouncement);
    }

    /**
     * 공지사항을 (이미지)파일과 같이 등록 한다.
     *
     * @param pushChatAnnouncement
     */
    @Override
    public void registerAnnouncementWithFile(PushChatAnnouncement pushChatAnnouncement, String uploadAnnouncementFilePath, String uploadAnnounceThumbnailPath, MultipartFile file) {
        logger.info("registerAnnouncementWithFile");

        // 이미지 파일명.
        String fileName = file.getOriginalFilename();

        // 파일 업로드 한다.
        try {
            InputStream inputStream = file.getInputStream();
            OutputStream outputStream = new FileOutputStream(uploadAnnouncementFilePath + fileName);

            int bytesRead;

            byte[] buffer = new byte[8192];

            while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 프로필 썸네일을 생성 한다.
        try {
            // 썸네일 크기를 설정 한다.
            int width = announcementThumbnailWidth;
            int height = announcementThumbnailHeight;

            // 원본 이미지 파일을 가져 온다.
            File src = new File(uploadAnnouncementFilePath + fileName);

            BufferedImage bufferedImage = ImageIO.read(src);

            // Aspect Ratio 를 유지하기 위해서 크기를 조정 한다.
            if((float)width/bufferedImage.getWidth() > (float)height/bufferedImage.getHeight()) {
                width = (int)(bufferedImage.getWidth() * ((float)height/bufferedImage.getHeight()));
            } else {
                height = (int)(bufferedImage.getHeight() * ((float)width/bufferedImage.getWidth()));
            }

            BufferedImage thImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            Graphics2D graphics2D = thImg.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.drawImage(bufferedImage, 0, 0, width, height, null);
            graphics2D.dispose();

            File destinationFile = new File(uploadAnnounceThumbnailPath + fileName);
            ImageIO.write(thImg, "png", destinationFile);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 공지사항와 (이미지)파일을 등록 한다.
        pushChatAnnouncementDao.registerAnnouncement(pushChatAnnouncement);
    }

    /**
     * 공지사항 목록을 가져 온다.
     *
     * @param pushChatAnnouncement
     * @return
     */
    @Override
    public List<PushChatAnnouncement> selectAnnouncementList(PushChatAnnouncement pushChatAnnouncement) {
        logger.info("selectAnnouncementList");
        return this.pushChatAnnouncementDao.selectAnnouncementList(pushChatAnnouncement);
    }

    /**
     * 공지사항 상세 내용을 가져 온다.
     *
     * @param pushChatAnnouncement
     * @return
     */
    @Override
    public PushChatAnnouncement selectAnnouncementInformation(PushChatAnnouncement pushChatAnnouncement) {
        logger.info("selectAnnouncementInformation");
        return this.pushChatAnnouncementDao.selectAnnouncementInformation(pushChatAnnouncement);
    }

    /**
     * 공지사항을 수정 한다.
     *
     * @param pushChatAnnouncement
     */
    @Override
    public void updateAnnouncement(PushChatAnnouncement pushChatAnnouncement) {
        logger.info("updateAnnouncement");
        this.pushChatAnnouncementDao.updateAnnouncement(pushChatAnnouncement);
    }

    /**
     * 공지사항을 (이미지)파일과 같이 수정 한다.
     *
     * @param pushChatAnnouncement
     */
    @Override
    public void updateAnnouncementWithFile(PushChatAnnouncement pushChatAnnouncement, String uploadAnnouncementFilePath, String uploadAnnounceThumbnailPath, MultipartFile file) {
        logger.info("updateAnnouncementWithFile");

        // 이미지 파일명.
        String fileName = file.getOriginalFilename();

        // 파일 업로드 한다.
        try {
            InputStream inputStream = file.getInputStream();
            OutputStream outputStream = new FileOutputStream(uploadAnnouncementFilePath + fileName);

            int bytesRead;

            byte[] buffer = new byte[8192];

            while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 프로필 썸네일을 생성 한다.
        try {
            // 썸네일 크기를 설정 한다.
            int width = announcementThumbnailWidth;
            int height = announcementThumbnailHeight;

            // 원본 이미지 파일을 가져 온다.
            File src = new File(uploadAnnouncementFilePath + fileName);

            BufferedImage bufferedImage = ImageIO.read(src);

            // Aspect Ratio 를 유지하기 위해서 크기를 조정 한다.
            if((float)width/bufferedImage.getWidth() > (float)height/bufferedImage.getHeight()) {
                width = (int)(bufferedImage.getWidth() * ((float)height/bufferedImage.getHeight()));
            } else {
                height = (int)(bufferedImage.getHeight() * ((float)width/bufferedImage.getWidth()));
            }

            BufferedImage thImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            Graphics2D graphics2D = thImg.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.drawImage(bufferedImage, 0, 0, width, height, null);
            graphics2D.dispose();

            File destinationFile = new File(uploadAnnounceThumbnailPath + fileName);
            ImageIO.write(thImg, "png", destinationFile);
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.pushChatAnnouncementDao.updateAnnouncement(pushChatAnnouncement);
    }

    /**
     * 공지사항을 비활성화 한다.
     *
     * @param pushChatAnnouncement
     */
    @Override
    public void updateDeactivateAnnouncement(PushChatAnnouncement pushChatAnnouncement) {
        logger.info("updateDeactivateAnnouncement");
        this.pushChatAnnouncementDao.updateDeactivateAnnouncement(pushChatAnnouncement);
    }
}
